package com.heima.media.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.common.aliyun.GreenImageScan;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.common.dto.ResponseResult;
import com.heima.common.minio.MinIOService;
import com.heima.common.util.SensitiveWordUtil;
import com.heima.media.dto.ArticleDto;
import com.heima.media.dto.ContentDto;
import com.heima.media.dto.ImageDto;
import com.heima.media.entity.WmChannel;
import com.heima.media.entity.WmNews;
import com.heima.media.entity.WmSensitive;
import com.heima.media.entity.WmUser;
import com.heima.media.feign.ArticleFeign;
import com.heima.media.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.redisson.api.RBlockingQueue;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.json.Json;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.TimeUnit;
@Slf4j
@Service
public class AuditServiceImpl implements IAuditService {

    @Autowired
    private GreenTextScan greenTextScan;
    @Autowired
    private GreenImageScan greenImageScan;
    @Autowired
    private ArticleFeign articleFeign;
    @Autowired
    @Lazy
    private IWmNewsService wmNewsService;
    @Autowired
    private MinIOService minIOService;
    @Autowired
    private IWmUserService wmUserService;
    @Autowired
    private IWmChannelService channelService;

    @Autowired
    private RedissonClient redissonClient;
    @Override
    @Async
    public void audit(Integer id) {
        WmNews wmNews = wmNewsService.getById(id);
        audit(wmNews);
    }

    @Override
    @Async
    public void audit(WmNews wmNews) {
          boolean isPass;
        //自敏感词的审核
          isPass =checkSensitive(wmNews);
          if(!isPass) return;
//        阿里云文本审核
          isPass =checkText(wmNews);
          if(!isPass) return;
//       阿里云的图片审核
          isPass =   checkImage(wmNews);
          if(!isPass) return;
//       保存app的文章
//        判断现在的时间是不是已经到达了发布时间
         if(System.currentTimeMillis() >= wmNews.getPublishTime().getTime()){
             Long articleId=saveArticle(wmNews);
             wmNews.setArticleId(articleId);
             wmNews.setStatus(9);
         }else{
             wmNews.setStatus(8);
             RBlockingQueue<String> blockingQueue = redissonClient.getBlockingQueue("article-dqueue");
             RDelayedQueue<String> delayedQueue = redissonClient.getDelayedQueue(blockingQueue);
             long time = wmNews.getPublishTime().getTime() - System.currentTimeMillis();
             delayedQueue.offer(wmNews.getId().toString(), time, TimeUnit.MILLISECONDS);
             log.info("消息发送成功，预计在"+time+"ms后，会执行一个方法");
         }
           wmNewsService.updateById(wmNews);

    }
    @Autowired
    private IWmSensitiveService wmSensitiveService;
    private boolean checkSensitive(WmNews wmNews) {
        //1.初始化敏感词map
        List<WmSensitive> wmSensitives = wmSensitiveService.list();
        List<String> list = new ArrayList<>();
        for (WmSensitive wmSensitive : wmSensitives) {
            list.add(wmSensitive.getSensitives());
        }
        SensitiveWordUtil.initMap(list);
        //2.对文章中的内容进行审核
        //获取文章中内容
        String text =  wmNews.getTitle();
        List<ContentDto> contentDtos =  JSON.parseArray(wmNews.getContent(), ContentDto.class);
        for (ContentDto contentDto : contentDtos) {
            if (contentDto.getType().equals("text")) {
                text += contentDto.getValue();
            }
        }
        Map<String, Integer> matchWords = SensitiveWordUtil.matchWords(text);
        //map为空说明没有敏感词
        if (matchWords.size()==0) {
            return true;
        }else {
            //不为空的话说明有敏感词，则返回false，并且告诉敏感词原因
            Set<String> keySet = matchWords.keySet();
            String reason = String.join(",", keySet);
            wmNews.setStatus(2);
            wmNews.setReason("敏感词审核未通过，原因是包含以下敏感词："+reason);
            //记着修改wmNews这样才能知道原因
            wmNewsService.updateById(wmNews);
            return false;
        }
    }

    //    根据wmNews 构建ArticleDto
    private Long saveArticle(WmNews wmNews) {
        ArticleDto articleDto = new ArticleDto();
        BeanUtils.copyProperties(wmNews,articleDto);
        articleDto.setId(null);
//        app用户可以申请成自媒体用户,自媒体用户自动就是文章作者
//        获取自媒体用户，自媒体用户中有AuthorId
        Integer userId = wmNews.getUserId();
        WmUser wmUser = wmUserService.getById(userId);
        articleDto.setAuthorId(wmUser.getApAuthorId());
        articleDto.setAuthorName(wmUser.getName());
        articleDto.setChannelId(wmNews.getChannelId());
        WmChannel wmChannel = channelService.getById(wmNews.getChannelId());
        articleDto.setChannelName(wmChannel.getName());
        articleDto.setLayout(wmNews.getType());
        articleDto.setFlag(0);
        List<ImageDto> imageDtoList = JSON.parseArray(wmNews.getImages(), ImageDto.class);
        List<String> urlList = new ArrayList<>();
        for (ImageDto imageDto : imageDtoList) {
            urlList.add(imageDto.getUrl());
        }
        articleDto.setImages(String.join(",",urlList)); // 格式不一样
        ResponseResult<Long> longResponseResult = articleFeign.saveArticle(articleDto);
        Long articleId = longResponseResult.getData();
        return articleId;
    }

    private boolean checkText(WmNews wmNews) {
//        文本包括：文章标题+文章的内容
       String text =  wmNews.getTitle();
        List<ContentDto> contentDtos =  JSON.parseArray(wmNews.getContent(), ContentDto.class);
        for (ContentDto contentDto : contentDtos) {
            if (contentDto.getType().equals("text")) {
                text += contentDto.getValue();
            }
        }

        boolean isPass = false;
        try {
//            suggestion
//            pass：文本正常，可以直接放行。
//            review：文本需要进一步人工审核。             label=porn
//            block：文本违规，可以直接删除或者限制公开。  label=porn
            Map map = greenTextScan.greenTextScan(text);
            String suggestion = (String) map.get("suggestion");
            if(suggestion.equals("pass")){
                isPass = true;
            }else if (suggestion.equals("review")){
                wmNews.setStatus(3);
                wmNews.setReason("阿里云文本审核未通过，需要人工审核，原因是：" + map.get("label")); //审核不通过或需要人工审核的原因
                wmNewsService.updateById(wmNews);
                isPass = false;
            }else{
                wmNews.setStatus(2);
                wmNews.setReason("阿里云文本审核未通过，原因是：" + map.get("label")); //审核不通过或需要人工审核的原因
                wmNewsService.updateById(wmNews);
                isPass = false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return isPass;
    }

    private boolean checkImage(WmNews wmNews) {

        boolean isPass = false;

        //图片包括：文章内容图片+文章的封面图片
        String coverImages =  wmNews.getImages(); //获取封面图片
        List<ImageDto> imageDtoList = JSON.parseArray(coverImages, ImageDto.class);
        List<ContentDto> contentDtos =  JSON.parseArray(wmNews.getContent(), ContentDto.class);
        for (ContentDto contentDto : contentDtos) {  //需要把内容图片放到imageDtoList中
            if (contentDto.getType().equals("image")) {
                ImageDto imageDto = new ImageDto();
                imageDto.setId(contentDto.getId());
                imageDto.setUrl(contentDto.getValue());
                if(!imageDtoList.contains(imageDto)){
                    //判断是否有重复的，如果有就不放入
                    imageDtoList.add(imageDto);
                }
            }
        }

        try {
            //现在的imageDtoList就是封面图片+内容图片
            List<byte[]> imageList = new ArrayList<>();
//        把图片都转成字节数组
            for (ImageDto imageDto : imageDtoList) {
                InputStream inputStream = minIOService.download(imageDto.getUrl());
                byte[] bytes = IOUtils.toByteArray(inputStream);
                imageList.add(bytes);
            }
//            suggestion
//            pass：文本正常，可以直接放行。
//            review：文本需要进一步人工审核。             label=porn
//            block：文本违规，可以直接删除或者限制公开。  label=porn
            Map map = greenImageScan.imageScan(imageList);
            String suggestion = (String) map.get("suggestion");
            if(suggestion.equals("pass")){
                isPass = true;
            }else if (suggestion.equals("review")){
                wmNews.setStatus(3);
                wmNews.setReason("阿里云图片审核未通过，需要人工审核，原因是：" + map.get("label")); //审核不通过或需要人工审核的原因
                wmNewsService.updateById(wmNews);
                isPass = false;
            }else{
                wmNews.setStatus(2);
                wmNews.setReason("阿里云图片审核未通过，原因是：" + map.get("label")); //审核不通过或需要人工审核的原因
                wmNewsService.updateById(wmNews);
                isPass = false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return isPass;
    }
}
